﻿using System;
using System.Diagnostics;
using System.IO;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;


namespace WITD
{
    /// <summary>
    ///  Contains TFS utility methods.
    /// </summary>
    public class TfsUtility
    {
        System.Diagnostics.Process WitCommand;
        String witCommandName = "witadmin";
        Logging Logger = new Logging();
        String _errorMessage;
        
        /// <summary>
        /// Constructor: Searches for thre WitAdmin.exe command line utility needed for some operations.
        /// </summary>
        public TfsUtility()
        {
            WitCommand = new System.Diagnostics.Process();
            WitCommand.ErrorDataReceived += new DataReceivedEventHandler(ProcessError);
            witCommandName = FindFile(witCommandName);
        }

        /// <summary>
        /// The last error message.
        /// </summary>
        public String ErrorMessage
        {
            get
            {
                return _errorMessage;
            }
        }
        /// <summary>
        /// The fully-qualified path to the WitAdmin.exe utility.
        /// </summary>
        public String WitCommandName
        {
            get
            {
                return witCommandName;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool WitAdminFound
        {
            get
            {
                return (!String.IsNullOrEmpty(witCommandName));
            }
        }
       
        #region Methods

        

        /// <summary>
        /// Returns a instance of the work item store.
        /// </summary>
        /// <param name="tfsName">
        /// The TFS server name.
        /// </param>
        /// <param name="noPrompt">
        /// <b>true</b> not to prompt for credential; otherwise <b>false</b>.
        /// </param>
        /// <returns>
        /// An instance of <see cref="WorkItemStore"/>.
        /// </returns>
        public static WorkItemStore GetWorkItemStore(string tfsName, bool noPrompt)
        {
            TfsTeamProjectCollection tfs = null;

            try
            {
                WorkItemStore store;
                ICredentialsProvider provider = null;

                if (!noPrompt)
                {
                    provider = new UICredentialsProvider();
                }

                tfs = new TfsTeamProjectCollection(TfsTeamProjectCollection.GetFullyQualifiedUriForName(tfsName), provider);
                tfs.EnsureAuthenticated();

                store = tfs.GetService<WorkItemStore>();

                return store;
            }

            finally
            {
                //per Microsoft.Reliability suggestion
                if (tfs != null) { tfs.Dispose(); }
            }
            
        }

        /// <summary>
        /// Executes the specified command with the specified command line.
        /// </summary>
        /// <param name="command">The executable to run.</param>
        /// <param name="commandLine">The arguments to pass to it.</param>
        /// <returns>The return code from the execution of the command.</returns>
        public int RunProcess(String command, String commandLine)
        {
            _errorMessage = "";
            WitCommand = new Process();
            WitCommand.Refresh();
            WitCommand.StartInfo = new System.Diagnostics.ProcessStartInfo(command, commandLine);
            WitCommand.StartInfo.UseShellExecute = false;
            WitCommand.StartInfo.RedirectStandardError = true;
            WitCommand.EnableRaisingEvents = true;
            WitCommand.StartInfo.CreateNoWindow = true;
            WitCommand.Start();

            WitCommand.BeginErrorReadLine();
            WitCommand.WaitForExit();

            return WitCommand.ExitCode;
        }

        /// <summary>
        /// Processes the error message from the last execution of the process object.
        /// </summary>
        /// <param name="sendingProcess">The Process object that generated the error.</param>
        /// <param name="errLine">The error message.</param>
        private void ProcessError(object sendingProcess, DataReceivedEventArgs errLine)
        {
            // Write the error text to the file if there is something
            // to write and an error file has been specified.
            if (!String.IsNullOrEmpty(errLine.Data))
            {
                _errorMessage = errLine.Data;
            }
        }

        /// <summary>
        /// Searches for WITAdmin.exe on the local hard disks.
        /// </summary>
        /// <param name="fileName">The filename to search for.</param>
        /// <returns>The fully-qualified path to the file, if found. Otherwise, an empty String.</returns>
        public String FindFile(String fileName)
        {
            foreach (DriveInfo d in System.IO.DriveInfo.GetDrives())
            {
                if (d.DriveType == DriveType.Fixed)
                {
                    foreach (String file in Directory.GetFiles(d.ToString() + "Program Files\\Microsoft Visual Studio 10.0\\Common7\\IDE", "witadmin.exe"))
                    {
                        if (file.ToUpper().Contains("WITADMIN.EXE"))
                        {
                            return file;
                        }
                    }
                }
            }

            //if not yet found, check 32 bit folder on a 64 bit system
            foreach (DriveInfo d in System.IO.DriveInfo.GetDrives())
            {
                if (d.DriveType == DriveType.Fixed)
                {
                    if (Directory.Exists(d.ToString() + "Program Files (x86)"))
                    {
                        foreach (String file in Directory.GetFiles(d.ToString() + "Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE", "witadmin.exe"))
                        {
                            if (file.ToUpper().Contains("WITADMIN.EXE"))
                            {
                                return file;
                            }
                        }
                    }
                }
            }
            // log this instead
            return String.Empty;
        }

        /// <summary>
        /// Determines if the specified collections are different.
        /// </summary>
        /// <param name="source">The source project collection.</param>
        /// <param name="target">The target project collection.</param>
        /// <returns>True if the collections are different. Otherwise false.</returns>
        public bool CollectionsDifferent(TfsTeamProjectCollection source, TfsTeamProjectCollection target)
        {
            if (source != null && target != null)
            {
                return (source.Uri.ToString() != target.Uri.ToString());
            }
            return true;
        }
        #endregion
    }
}
